/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2023-2024.
 * Description: RTOS Process Context for RPC asm header
 * Create: 2023-08-15
 */
#ifndef __ASM_RTOS_RTPC_RPC_H_
#define __ASM_RTOS_RTPC_RPC_H_

#include <asm/ptrace.h>
#include <asm/sysreg.h>
#include <asm/memory.h>
#include <asm/esr.h>

#define REG_X1	1
#define REG_X8	8

/* TTBR0_EL1 bit assignments: ASID：63-48, BADDR：47-1, CnP: 0 */
#define BADDR_SIZE_BITS  48
#define BADDR_MASK       (((1UL << BADDR_SIZE_BITS) - 1) & ~TTBR_CNP_BIT)

static inline int get_scno(const struct pt_regs *regs)
{
	// scno in aarch64 is an int saved in regs[8]
	// see do_el0_svc->el0_svc_common
	return regs->regs[REG_X8];
}

static inline unsigned long get_cmd(const struct pt_regs *regs)
{
	return regs->regs[REG_X1];
}

static inline bool is_pgtable_diff_check(struct task_struct *tsk)
{
	unsigned long ttbr0_el1;

	ttbr0_el1 = read_sysreg(ttbr0_el1);
	if (phys_to_virt(ttbr0_el1 & BADDR_MASK) != tsk->mm->pgd)
		return true;

	return false;
}

static inline bool is_syscall(unsigned long is_el0_sync)
{
	unsigned long esr_el1;

	if (is_el0_sync) {
		esr_el1 = read_sysreg(esr_el1);
		esr_el1 = ESR_ELx_EC(esr_el1);
		if (esr_el1 == ESR_ELx_EC_SVC64)
			return true;
	}

	return false;
}

static inline void rtpc_set_return_value(struct pt_regs *regs, unsigned long val)
{
	regs->user_regs.regs[0] = val;
}
#endif
